Skip to content

chore(key-wallet): drop the unused vendored PSBT implementation - #1041

Merged
ZocoLini merged 1 commit into
devfrom
chore/drop-unused-psbt-module
Sep 23, 2026
Merged

ZocoLini merged 1 commit into
devfrom
chore/drop-unused-psbt-module

Conversation

@ZocoLini

@ZocoLini ZocoLini commented Sep 20, 2026 •

Copy link
Copy Markdown
Collaborator

A security report pointed out that PartiallySignedTransaction::sign() signs each input with whatever sighash type the input declares, with no BIP174 whitelist: a hostile coordinator can set SIGHASH_NONE|ANYONECANPAY (0x82) on an input and the victim's signature is then valid for any other transaction spending that same input.

The claim is accurate. sighash_ecdsa() only checked that the value was one of the six standard types, and 0x82 is standard. The behaviour is not ours, though: the whole module is a verbatim copy of rust-bitcoin's psbt (same sign(), same sighash_ecdsa(), same doc comments as bitcoin 0.32.5), which leaves the check to the BIP174 Signer role.

Rather than add the whitelist, the module goes away, because nothing used it:

  • No other module in this workspace referenced key_wallet::psbt. TransactionBuilder does its own signing and hardcodes EcdsaSighashType::All.
  • key-wallet-ffi and dash-spv-ffi expose no PSBT symbol, so the mobile wallets could never reach it.
  • dashpay/platform, the one repository that depends on key-wallet by git, has zero occurrences of psbt in any .rs/.toml/.ts/.js file.
  • The two examples that did use it, ecdsa-psbt and taproot-psbt, declared required-features = ["bitcoinconsensus"] — a feature that does not exist in dash/Cargo.toml — so they have never once compiled.

Most of it was meaningless here anyway: output_type() resolved inputs to Wpkh, Wsh, ShWpkh and Tr, computing segwit and taproot sighashes for a chain that has neither. Only Bare and Sh were reachable.

Removed with it: the BIP174 vector test and its fixtures, the two examples plus the dash -> key-wallet dev-dependency cycle they created, the dash_deserialize_psbt fuzz target and key-wallet as a dash-fuzz dependency, key-wallet's now-unused optional base64 dependency, and ScriptBuf::p2wpkh_script_code() with Script::v0_p2wpkh(), whose only callers in the workspace were the PSBT signer and each other.

walletcreatefundedpsbt and friends in rpc-client are Dash Core RPC methods, not this code, and stay.

Verified: cargo build --workspace --all-targets, cargo clippy --workspace --all-targets --all-features with no warnings, cargo fmt --check, cargo test -p key-wallet --all-features (646 passed), cargo test -p dashcore --all-features (628 + 37 + 12 + 1 passed), cargo doc with no broken intra-doc links.

PR Hygiene · b45a13c

  • Bots — coderabbitai ✓
  • Self-review — post /self-reviewed
  • Within your 5 open PRs
  • Build running
  • Approvals
    • files with no dedicated owner (README.md, dash/Cargo.toml, dash/examples/ecdsa-psbt.rs and 9 more) — QuantumExplorer or xdustinface
    • key-wallet (key-wallet/Cargo.toml, key-wallet/README.md, key-wallet/TODO.md and 27 more) — QuantumExplorer or xdustinface

When every box is checked the PR Hygiene check passes and this can merge.

Summary by CodeRabbit

  • Removed Features
    • Removed PSBT creation, editing, signing, merging, and finalization support from the key wallet, along with related examples and documentation.
    • Removed public script helpers for extracting P2WPKH programs and generating P2WPKH script code.

@coderabbitai

coderabbitai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: dashpay/rust-dashcore/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: d955d18a-ed4a-463a-afd6-9d1b314d8d19

📥 Commits

Reviewing files that changed from the base of the PR and between 342cb29 and b45a13c.

📒 Files selected for processing (42)
  • README.md
  • dash/Cargo.toml
  • dash/examples/ecdsa-psbt.rs
  • dash/examples/taproot-psbt.rs
  • dash/src/blockdata/script/borrowed.rs
  • dash/src/blockdata/script/owned.rs
  • dash/src/blockdata/transaction/mod.rs
  • dash/src/lib.rs
  • fuzz/Cargo.toml
  • fuzz/fuzz-util.sh
  • fuzz/fuzz_targets/dash/deserialize_psbt.rs
  • fuzz/generate-files.sh
  • key-wallet/Cargo.toml
  • key-wallet/README.md
  • key-wallet/TODO.md
  • key-wallet/src/lib.rs
  • key-wallet/src/psbt/error.rs
  • key-wallet/src/psbt/macros.rs
  • key-wallet/src/psbt/map/global.rs
  • key-wallet/src/psbt/map/input.rs
  • key-wallet/src/psbt/map/mod.rs
  • key-wallet/src/psbt/map/output.rs
  • key-wallet/src/psbt/mod.rs
  • key-wallet/src/psbt/raw.rs
  • key-wallet/src/psbt/serialize.rs
  • key-wallet/tests/data/combine_psbt_hex
  • key-wallet/tests/data/create_psbt_hex
  • key-wallet/tests/data/extract_tx_hex
  • key-wallet/tests/data/finalize_psbt_hex
  • key-wallet/tests/data/lex_combine_psbt_hex
  • key-wallet/tests/data/lex_psbt_1_hex
  • key-wallet/tests/data/lex_psbt_2_hex
  • key-wallet/tests/data/previous_tx_0_hex
  • key-wallet/tests/data/previous_tx_1_hex
  • key-wallet/tests/data/psbt1.hex
  • key-wallet/tests/data/psbt2.hex
  • key-wallet/tests/data/psbt_combined.hex
  • key-wallet/tests/data/sign_1_psbt_hex
  • key-wallet/tests/data/sign_2_psbt_hex
  • key-wallet/tests/data/update_1_psbt_hex
  • key-wallet/tests/data/update_2_psbt_hex
  • key-wallet/tests/psbt.rs
💤 Files with no reviewable changes (38)
  • fuzz/generate-files.sh
  • key-wallet/tests/data/psbt_combined.hex
  • dash/Cargo.toml
  • key-wallet/src/psbt/map/global.rs
  • key-wallet/tests/data/psbt2.hex
  • key-wallet/tests/data/sign_1_psbt_hex
  • dash/src/blockdata/script/owned.rs
  • key-wallet/src/psbt/error.rs
  • key-wallet/src/psbt/serialize.rs
  • key-wallet/tests/data/previous_tx_0_hex
  • key-wallet/tests/data/combine_psbt_hex
  • key-wallet/README.md
  • key-wallet/tests/data/finalize_psbt_hex
  • key-wallet/tests/data/update_2_psbt_hex
  • key-wallet/src/lib.rs
  • key-wallet/tests/data/previous_tx_1_hex
  • key-wallet/tests/psbt.rs
  • key-wallet/tests/data/sign_2_psbt_hex
  • key-wallet/tests/data/lex_combine_psbt_hex
  • key-wallet/tests/data/psbt1.hex
  • dash/examples/ecdsa-psbt.rs
  • key-wallet/tests/data/create_psbt_hex
  • dash/examples/taproot-psbt.rs
  • key-wallet/tests/data/lex_psbt_2_hex
  • key-wallet/Cargo.toml
  • key-wallet/tests/data/lex_psbt_1_hex
  • key-wallet/src/psbt/raw.rs
  • key-wallet/src/psbt/map/output.rs
  • README.md
  • key-wallet/src/psbt/map/mod.rs
  • key-wallet/src/psbt/mod.rs
  • key-wallet/src/psbt/macros.rs
  • key-wallet/TODO.md
  • fuzz/fuzz_targets/dash/deserialize_psbt.rs
  • key-wallet/tests/data/update_1_psbt_hex
  • key-wallet/src/psbt/map/input.rs
  • key-wallet/tests/data/extract_tx_hex
  • fuzz/Cargo.toml

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The change removes key-wallet’s PSBT module, related tests and fixtures, Dash PSBT examples and script helpers, and the PSBT fuzz target. It also removes PSBT references from project documentation and updates related manifests and fuzz scripts.

Changes

PSBT support removal

Layer / File(s) Summary
Remove key-wallet PSBT API and implementation
key-wallet/src/lib.rs, key-wallet/src/psbt/*, key-wallet/Cargo.toml, key-wallet/tests/*, key-wallet/README.md, key-wallet/TODO.md
The public PSBT module and its implementation, types, tests, and test fixtures are removed. The optional base64 dependency and PSBT documentation references are also removed.
Remove Dash PSBT examples and helpers
dash/Cargo.toml, dash/examples/*psbt.rs, dash/src/blockdata/script/*, dash/src/blockdata/transaction/mod.rs, dash/src/lib.rs, README.md
The ECDSA and Taproot PSBT examples and Cargo targets are removed. Two P2WPKH script methods are removed, and Dash documentation no longer refers to PSBT support.
Remove PSBT fuzz target wiring
fuzz/Cargo.toml, fuzz/fuzz-util.sh, fuzz/fuzz_targets/dash/*, fuzz/generate-files.sh
The PSBT deserialization fuzz target and manifest entry are removed. The generated manifest no longer includes the key-wallet dependency, and the CI exclusion filter no longer lists the PSBT target.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers: quantumexplorer

Merge Risk: ⚪ Minimal · up to b45a1

The supplied evidence identifies no remaining issue that should delay merging this PSBT removal.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: removing the unused vendored PSBT implementation from key-wallet and its related scope.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.01%. Comparing base (342cb29) to head (b45a13c).

Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #1041      +/-   ##
==========================================
- Coverage   77.11%   77.01%   -0.10%     
==========================================
  Files         329      320       -9     
  Lines       83577    81519    -2058     
==========================================
- Hits        64447    62780    -1667     
+ Misses      19130    18739     -391     
Flag Coverage Δ
core 78.23% <ø> (+0.04%) ⬆️
ffi 49.30% <ø> (ø)
rpc 20.00% <ø> (ø)
spv 92.07% <ø> (+0.01%) ⬆️
wallet 80.21% <ø> (-0.13%) ⬇️
Files with missing lines Coverage Δ
dash/src/blockdata/script/borrowed.rs 76.12% <ø> (+1.67%) ⬆️
dash/src/blockdata/script/owned.rs 69.83% <ø> (+4.04%) ⬆️
dash/src/blockdata/transaction/mod.rs 86.76% <ø> (ø)

... and 7 files with indirect coverage changes

@github-actions github-actions Bot added the merge-conflict The PR conflicts with the target branch. label Sep 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This PR has merge conflicts with the base branch. Please rebase or merge the base branch into your branch to resolve them.

@ZocoLini
ZocoLini force-pushed the chore/drop-unused-psbt-module branch from c8240d7 to 1fba9b1 Compare September 22, 2026 16:05
@github-actions github-actions Bot removed the merge-conflict The PR conflicts with the target branch. label Sep 22, 2026
@ZocoLini ZocoLini closed this Sep 22, 2026
@ZocoLini ZocoLini reopened this Sep 22, 2026
@ZocoLini
ZocoLini marked this pull request as ready for review September 23, 2026 18:14
@github-actions

github-actions Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Bots are done — your move: post /self-reviewed.
Full checklist in the description.

@github-actions github-actions Bot added waiting-self-review Waiting for the author to post /self-reviewed bot-review-skipped A required review bot did not report; it was skipped by the window or by a person. labels Sep 23, 2026
A security report pointed out that `PartiallySignedTransaction::sign()`
signs each input with whatever sighash type the input declares, with no
BIP174 whitelist: a hostile coordinator can set SIGHASH_NONE|ANYONECANPAY
(0x82) on an input and the victim's signature is then valid for any other
transaction spending that same input.

The claim is accurate. `sighash_ecdsa()` only checked that the value was
one of the six standard types, and 0x82 is standard. The behaviour is not
ours, though: the whole module is a verbatim copy of rust-bitcoin's psbt
(same `sign()`, same `sighash_ecdsa()`, same doc comments as bitcoin
0.32.5), which leaves the check to the BIP174 Signer role.

Rather than add the whitelist, the module goes away, because nothing used
it:

- No other module in this workspace referenced `key_wallet::psbt`.
  `TransactionBuilder` does its own signing and hardcodes
  `EcdsaSighashType::All`.
- `key-wallet-ffi` and `dash-spv-ffi` expose no PSBT symbol, so the mobile
  wallets could never reach it.
- dashpay/platform, the one repository that depends on key-wallet by git,
  has zero occurrences of `psbt` in any .rs/.toml/.ts/.js file.
- The two examples that did use it, `ecdsa-psbt` and `taproot-psbt`,
  declared `required-features = ["bitcoinconsensus"]` — a feature that
  does not exist in dash/Cargo.toml — so they have never once compiled.

Most of it was meaningless here anyway: `output_type()` resolved inputs to
`Wpkh`, `Wsh`, `ShWpkh` and `Tr`, computing segwit and taproot sighashes
for a chain that has neither. Only `Bare` and `Sh` were reachable.

Removed with it: the BIP174 vector test and its fixtures, the two
examples plus the dash -> key-wallet dev-dependency cycle they created,
the `dash_deserialize_psbt` fuzz target and key-wallet as a dash-fuzz
dependency, key-wallet's now-unused optional `base64` dependency, and
`ScriptBuf::p2wpkh_script_code()` with `Script::v0_p2wpkh()`, whose only
callers in the workspace were the PSBT signer and each other.

`walletcreatefundedpsbt` and friends in rpc-client are Dash Core RPC
methods, not this code, and stay.

Verified: cargo build --workspace --all-targets, cargo clippy --workspace
--all-targets --all-features with no warnings, cargo fmt --check,
cargo test -p key-wallet --all-features (646 passed), cargo test -p
dashcore --all-features (628 + 37 + 12 + 1 passed), cargo doc with no
broken intra-doc links.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ZocoLini
ZocoLini force-pushed the chore/drop-unused-psbt-module branch from 1fba9b1 to b45a13c Compare September 23, 2026 19:03
@github-actions github-actions Bot added waiting-bots Waiting for the review bots to report on this head and removed waiting-self-review Waiting for the author to post /self-reviewed bot-review-skipped A required review bot did not report; it was skipped by the window or by a person. labels Sep 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Bots are done — your move: post /self-reviewed.
Full checklist in the description.

@github-actions github-actions Bot added waiting-self-review Waiting for the author to post /self-reviewed and removed waiting-bots Waiting for the review bots to report on this head labels Sep 23, 2026
@ZocoLini
ZocoLini merged commit 65f11cd into dev Sep 23, 2026
40 of 41 checks passed
@ZocoLini
ZocoLini deleted the chore/drop-unused-psbt-module branch September 23, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-self-review Waiting for the author to post /self-reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant